/************************************************/
/*    Auteur    : Yoann NICOD                   */
/*    Programme : Atomic Bomberman Origins      */
/*    Fichier   : serveur.cpp                   */
/*    Date      : 27/12/2012                    */
/************************************************/

#include <iostream>
#include "serveur.h"
#include "debug.h" 
#include "general.h"

JoueurReseau::JoueurReseau()
{
	m_ID = -1;
}

JoueurReseau::~JoueurReseau()
{
}

Serveur::Serveur() : m_ThreadEcouteClient(&Serveur::LanceurThreadEcouteClients, (void *)this)
{
	Log("Serveur demarre", 1);
	for(int i = 0; i < NOMBRE_JOUEURS_MAX; ++i)
		m_ListeJoueursReseau[i] = NULL;
	m_ThreadEcouteClient.Launch();
}

Serveur::~Serveur()
{
	Log("Arret du serveur", 1);
	/////
//	Supprimer les instances de JoueurReseau
	/////
}

void Serveur::EnvoyerATous(Packet MonPaquet, int Sauf)
{
	for(int i = 0; i < NOMBRE_JOUEURS_MAX; ++i)
	{
		JoueurReseau *pJoueur = m_ListeJoueursReseau[i];
		Socket::Status StatutCourant;

		if(pJoueur != NULL && pJoueur->m_ID != Sauf)
		{
			StatutCourant = pJoueur->m_SocketClient.Send(MonPaquet);
			if(StatutCourant != Socket::Status::Done)
				NotifierClientDeconnecte(pJoueur->m_ID);
		}
	}
}

void Serveur::LancerPartie()
{
	return;
}

void Serveur::DeconnecterClient(int IDClient)
{
	delete m_ListeJoueursReseau[IDClient];
	m_ListeJoueursReseau[IDClient] = NULL;

	char Buf[64] = {0};
	sprintf(Buf, "Client %d deconnecte", IDClient);
	Log(Buf, 1);

	return;
}

void Serveur::NotifierClientDeconnecte(int IDClient)
{
	char Buf[64] = {0};
	sprintf(Buf, "Client %d deconnecte", IDClient);
	Log(Buf, 1);

	delete m_ListeJoueursReseau[IDClient];
	m_ListeJoueursReseau[IDClient] = NULL;
	
	return;
}

void Serveur::LanceurThreadEcouteClients(void *pParam)
{
	Serveur *pServeur = (Serveur *)pParam;
	pServeur->ThreadEcouteClients();

	return;
}

void Serveur::ThreadEcouteClients()
{
	char Buf[64] = {0};

	Log("Serveur en attente de clients", 1);

	m_SocketAccueilClients.Listen(PORT);
	while(1)
	{
		sf::IPAddress AdresseClient;
		sf::SocketTCP ClientConnecte;
		if (m_SocketAccueilClients.Accept(ClientConnecte, &AdresseClient) == sf::Socket::Done)
		{
			sprintf(Buf, "Nouveau client connecte : %s", AdresseClient.ToString().c_str());
			Log(Buf, 1);

			JoueurReseau *pNouveauJoueur = new JoueurReseau;
			if(pNouveauJoueur == NULL)
				Log("\tImpossible d'allouer la memoire pour ce client", 1);
			else
			{
				pNouveauJoueur->m_ID = RechercherIDClientDisponible();
				if(pNouveauJoueur->m_ID == -1)
					Log("\tErreur fatale, aucun ID disponible pour le nouveau client", 1);
				else
				{
					sprintf(Buf, "\tID alloue : %d", pNouveauJoueur->m_ID);
					Log(Buf, 1);
					pNouveauJoueur->m_SocketClient = ClientConnecte;
					m_ListeJoueursReseau[pNouveauJoueur->m_ID] = pNouveauJoueur;

					m_SelecteurClients.Add(m_ListeJoueursReseau[pNouveauJoueur->m_ID]->m_SocketClient);
				}
			}
		}
	}

	return;
}

int Serveur::RechercherIDClientDisponible()
{
	for(int i = 0; i < NOMBRE_JOUEURS_MAX; ++i)
		if(m_ListeJoueursReseau[i] == NULL)
			return i;
	
	return -1;
}

JoueurReseau *Serveur::GetJoueurReseauParID(int IDClient)
{
	for(int i = 0; i < NOMBRE_JOUEURS_MAX; ++i)
		if(m_ListeJoueursReseau[i] != NULL && m_ListeJoueursReseau[i]->m_ID == IDClient)
			return m_ListeJoueursReseau[i];
	
	return NULL;
}